home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / grn / RCS / main.c,v < prev   
Encoding:
Text File  |  1991-12-12  |  22.8 KB  |  800 lines

  1. head     1.3;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    shirriff:1.3; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.3
  10. date     89.12.12.20.19.44;  author mendel;  state Exp;
  11. branches ;
  12. next     1.2;
  13.  
  14. 1.2
  15. date     88.12.18.11.56.47;  author ouster;  state Exp;
  16. branches ;
  17. next     1.1;
  18.  
  19. 1.1
  20. date     88.12.18.11.35.08;  author ouster;  state Exp;
  21. branches ;
  22. next     ;
  23.  
  24.  
  25. desc
  26. @@
  27.  
  28.  
  29. 1.3
  30. log
  31. @Added exit(0); in main.
  32. @
  33. text
  34. @/*    main.c    1.24    (Berkeley)    86/04/14
  35.  *
  36.  *    This file contains the main and file system dependent routines
  37.  * for processing gremlin files into troff input.  The program watches
  38.  * input go by to standard output, only interpretting things between .GS
  39.  * and .GE lines.  Default values (font, size, scale, thickness) may be
  40.  * overridden with a "default" command and are further overridden by
  41.  * commands in the input.  A description of the command-line options are
  42.  * listed below.  A space is NOT required for the operand of an option.
  43.  *
  44.  *    command options are:
  45.  *
  46.  *    -L dir    set the library directory to dir.  If a file is not found
  47.  *        in the current directory, it is looked for in dir (default
  48.  *        is /usr/lib/gremlib).
  49.  *
  50.  *    -T dev    Prepare output for "dev" printer.  Default is for the varian
  51.  *    -P dev    and versatec printers.  Devices acceptable are:  ver, var, ip.
  52.  *
  53.  *        Inside the GS and GE, commands are accepted to reconfigure
  54.  *        the picture.  At most one command may reside on each line, and
  55.  *        each command is followed by a parameter separated by white space.
  56.  *        The commands are as follows, and may be abbreviated down to one
  57.  *        character (with exception of "scale" and "stipple" down to "sc"
  58.  *        and "st") and may be upper or lower case.
  59.  *
  60.  *                  default  -  make all settings in the current
  61.  *                      .GS/.GE the global defaults.
  62.  *                      Height, width and file are NOT saved.
  63.  *               1, 2, 3, 4  -  set size 1, 2, 3, or 4 (followed
  64.  *                      by an integer point size).
  65.  *    roman, italics, bold, special  -  set gremlin's fonts to any other
  66.  *                      troff font (one or two characters)
  67.  *               stipple, l  -  use a stipple font for polygons.  Arg
  68.  *                      is troff font name.  No Default.  Can
  69.  *                      use only one stipple font per picture.
  70.  *                      (see below for stipple font index)
  71.  *                 scale, x  -  scale is IN ADDITION to the global
  72.  *                      scale factor from the default.
  73.  *               pointscale  -  turn on scaling point sizes to
  74.  *                      match "scale" commands.  (optional
  75.  *                      operand "off" to turn it off)
  76.  *        narrow, medium, thick  -  set pixel widths of lines.
  77.  *                 file  -  set the file name to read the
  78.  *                      gremlin picture from.  If the file
  79.  *                      isn't in the current directory, the
  80.  *                      gremlin library is tried.
  81.  *            width, height  -  these two commands override any
  82.  *                      scaling factor that is in effect,
  83.  *                      and forces the picture to fit into
  84.  *                      either the height or width specified,
  85.  *                      whichever makes the picture smaller.
  86.  *                      The operand for these two commands is
  87.  *                      a floating-point number in units of
  88.  *                      inches
  89.  *                oldstipplemap  -  use the old-style stipple mapping.
  90.  *                      THE FOLLOWING COMMANDS ARE IGNORED
  91.  *                      UNLESS OLDSTIPPLEMAP IS SPECIFIED.
  92.  *     l1, l2, l3, l4, l5, l6, l7, l8  -  set association between stipples
  93.  *                      (1 - 8) and the stipple font file
  94.  *                      index.  Valid cifplot indices are
  95.  *                      1 - 32 (although 24 is not defined)
  96.  *                      and valid unigrafix indices are
  97.  *                      1 - 64.  Nonetheless, any number
  98.  *                      between 0 and 255 is accepted since
  99.  *                      new stipple fonts may be added.
  100.  *                      An integer operand is required.
  101.  *
  102.  *    Troff number registers used:  g1 through g9.  g1 is the width of the
  103.  *    picture, and g2 is the height.  g3, and g4, save information, g8
  104.  *    and g9 are used for text processing and g5-g7 are reserved.
  105.  */
  106.  
  107.  
  108. #include <ctype.h>
  109. #include "gprint.h"
  110. #include "dev.h"
  111.  
  112. extern char *malloc();
  113. extern char *rindex();
  114.  
  115. /* database imports */
  116.  
  117. extern HGPrintElt();
  118. extern ELT *DBInit(), *DBRead();
  119. extern POINT *PTInit(), *PTMakePoint();
  120.  
  121.  
  122. #ifndef GREMLIB
  123. #define GREMLIB        "/usr/local/gremlib/"
  124. #endif
  125.  
  126. #define SUN_SCALEFACTOR 0.70
  127.  
  128. #ifndef DEVDIR
  129. #define DEVDIR        "/usr/lib/font"
  130. #endif
  131. #define DEFAULTDEV    "va"
  132. #define DEFSTIPPLE    "cf"
  133.  
  134. #define MAXINLINE    100        /* input line length */
  135. #define DEFTHICK    3        /* default thicknes */
  136. #define DEFSTYLE    SOLID        /* default line style */
  137.  
  138. #ifdef oldversion
  139. #define SCREENtoINCH    0.02        /* scaling factor, screen to inches */
  140. #endif
  141.  
  142. double SCREENtoINCH;            /* scaling factor, screen to inches */
  143.  
  144. #define BIG    999999999999.0        /* unweildly large floating number */
  145.  
  146.  
  147. static char sccsid[] = "@@(#) (Berkeley) 4/14/86";
  148.  
  149. char    *printer = DEFAULTDEV;    /* device to look up resolution of */
  150. char    *gremlib = GREMLIB;    /* place to find files after current dir. */
  151. double    res;            /* that printer's resolution goes here */
  152.  
  153. int    linethickness;        /* brush styles */
  154. int    linmod;
  155. int    brushinvalid = 1;    /* non-zero means ditroff doesn't know about
  156.                  * our linethickness and linmod. */
  157. int    lastx;            /* point registers for printing elements */
  158. int    lasty;
  159. int    lastyline;        /* a line's vertical position is NOT the same */
  160.                 /* after that line is over, so for a line of */
  161.                 /* drawing commands, vertical spacing is kept */
  162.                 /* in lastyline */
  163.  
  164.             /* these are the default fonts, sizes, line styles, */
  165.             /*   and thicknesses.  These can be modified from a */
  166.             /*   "default" command and are reset each time the  */
  167.             /*   start of a picture (.GS) is found.            */
  168.  
  169. char *    deffont[] = {  "R", "I", "B", "S"  };
  170. int    defsize[] = {  10, 16, 24, 36  };
  171. int    defthick[STYLES] = {  1, 1, 5, 1, 1, 3  };
  172. int    defstipple_index[NSTIPPLES] = { 1, 3, 12, 14, 16, 19, 21, 23 };
  173. int    style[STYLES] = {  DOTTED, DOTDASHED, SOLID, DASHED, SOLID, SOLID  };
  174. double    scale = 1.0;        /* no scaling, default */
  175. int    defpoint = 0;        /* flag for pointsize scaling */
  176. char *  defstipple = (char *) 0;
  177.  
  178. int    thick[STYLES];    /* thicknesses set by defaults, then by commands */
  179. char    *tfont[FONTS];    /* fonts originally set to deffont values, then */
  180. int     tsize[SIZES];    /*    optionally changed by commands inside grn */
  181. int    stipple_index[NSTIPPLES];    /* stipple font file indices */
  182. char *  stipple;
  183.  
  184. double    xscale;        /* scaling factor from individual pictures */
  185. double    troffscale;    /* scaling factor at output time */ 
  186. double    width;        /* user-request maximum width for picture (in inches) */
  187. double    height;        /* user-request height */
  188. int    pointscale;    /* flag for pointsize scaling */
  189. int    setdefault;    /* flag for a .GS/.GE to remember all settings */
  190.  
  191. double    toppoint;        /* remember the picture */
  192. double    bottompoint;        /* bounds in these variables */
  193. double    leftpoint;
  194. double    rightpoint;
  195.  
  196. int    ytop;            /* these are integer versions of the above */
  197. int    ybottom;        /* so not to convert each time they're used */
  198. int    xleft;
  199. int    xright;
  200.  
  201. char    *filename = NULL;            /* name of input file */
  202. int    linenum = 0;            /* line number of input file */
  203. char    inputline[MAXINLINE];        /* spot to filter through the file */
  204. char    *c1 = inputline;        /* c1, c2, and c3 will be used to */
  205. char    *c2 = inputline + 1;        /* hunt for lines that begin with */
  206. char    *c3 = inputline + 2;        /* ".GS" by looking individually */
  207. char    GScommand[MAXINLINE];        /* put user's ".GS" command line here */
  208. char    gremlinfile[MAXINLINE];        /* filename to use for a picture */
  209. int    SUNFILE = FALSE;        /* TRUE if SUN gremlin file */
  210. int    oldstipmap = FALSE;        /* TRUE if old-style stipple mapping */
  211.  
  212. char *doinput();
  213.  
  214.  
  215. /*----------------------------------------------------------------------------*
  216.  | Routine:    main (argument_count, argument_pointer)
  217.  |
  218.  | Results:    parses the command line, accumulating input file names, then
  219.  |        reads the inputs, passing it directly to output until a ".GS"
  220.  |        line is read.  Main then passes control to "conv" to do the
  221.  |        gremlin file conversions.
  222.  *----------------------------------------------------------------------------*/
  223.  
  224. main(argc, argv)
  225. int argc;
  226. char **argv;
  227. {
  228.     register FILE *fp;
  229.     register int k;
  230.     register char c;
  231.     register gfil = 0;
  232.     char *file[50];
  233.  
  234.     char *operand();
  235.     char *getenv();
  236.  
  237.  
  238.     if (fp = (FILE *) getenv("PRINTER")) printer = (char *) fp;
  239.     if (fp = (FILE *) getenv("TYPESETTER")) printer = (char *) fp;
  240.     while (--argc) {
  241.         if (**++argv != '-')
  242.         file[gfil++] = *argv;
  243.         else
  244.           switch (c = (*argv)[1]) {
  245.  
  246.         case 0:
  247.             file[gfil++] = NULL;
  248.             break;
  249.  
  250.         case 'P':
  251.         case 'T':    /* final output typesetter name */
  252.             printer = operand(&argc, &argv);
  253.             break;
  254.  
  255.         case 'L':    /* set library directory */
  256.             gremlib = operand(&argc, &argv);
  257.             break;
  258.  
  259.         default:
  260.             error("unknown switch: %c", c);
  261.         }
  262.     }
  263.                 /* set the resolution for an output device */
  264.     getres(printer);    /* named in "printer" */
  265.  
  266.     if (gfil == 0) {    /* no filename, use standard input */
  267.         file[0] = NULL;
  268.         gfil++;
  269.     }
  270.  
  271.     for (k=0; k<gfil; k++) {
  272.         filename = file[k];
  273.         linenum = 0;
  274.         if (filename != NULL) {
  275.             if ((fp = fopen(filename, "r")) == NULL) {
  276.                 error("can't open file");
  277.                 exit(1);
  278.             }
  279.         } else
  280.             fp = stdin;
  281.         while (doinput(fp) != NULL) {
  282.             if (*c1 == '.' && *c2 == 'G' && *c3 == 'S') {
  283.                 conv(fp);
  284.             } else {
  285.                 fputs(inputline, stdout);
  286.             }
  287.         }
  288.     }
  289.     exit(0);
  290. }
  291.  
  292.  
  293. /*----------------------------------------------------------------------------*
  294.  | Routine:    error (control_string, args, . . . )
  295.  |
  296.  | Results:    prints ("grn: ", the control_string + args, "\n") to stderr
  297.  *----------------------------------------------------------------------------*/
  298.  
  299. /* VARARGS1 */
  300. error(s, a1, a2, a3, a4)
  301. char *    s;
  302. {
  303.     fprintf(stderr, "grn: ");
  304.     if (filename) fprintf(stderr, "\"%s\": ",filename);
  305.     if (linenum) fprintf(stderr, "line %d: ",linenum);
  306.     fprintf(stderr, s, a1, a2, a3, a4);
  307.     fprintf(stderr, "\n");
  308. }
  309.  
  310.  
  311. /*----------------------------------------------------------------------------*
  312.  | Routine:    char  * operand (& argc,  & argv)
  313.  |
  314.  | Results:    returns address of the operand given with a command-line
  315.  |        option.  It uses either "-Xoperand" or "-X operand", whichever
  316.  |        is present.  The program is terminated if no option is present.
  317.  |
  318.  | Side Efct:    argc and argv are updated as necessary.
  319.  *----------------------------------------------------------------------------*/
  320.  
  321. char *operand(argcp, argvp)
  322. int * argcp;
  323. char ***argvp;
  324. {
  325.     if ((**argvp)[2]) return(**argvp + 2); /* operand immediately follows */
  326.     if ((--*argcp) <= 0) {            /* no operand */
  327.         error("command-line option operand missing.");
  328.         exit(8);
  329.     }
  330.     return(*(++(*argvp)));            /* operand is next word */
  331. }
  332.  
  333.  
  334. /*----------------------------------------------------------------------------*
  335.  | Routine:    getres (device_name)
  336.  |
  337.  | Results:    sets "res" to the resolution of the output device specified
  338.  |        by the string dev.
  339.  *----------------------------------------------------------------------------*/
  340.  
  341. getres(name)
  342. char *name;
  343. {
  344.     int fin;
  345.     struct dev device;
  346.     char temp[60];
  347.  
  348.     sprintf(temp, "%s/dev%s/DESC.out", DEVDIR, name);
  349.     if ((fin = open(temp, 0)) < 0) {
  350.         error("can't open tables for %s", temp);
  351.         exit(1);
  352.     }
  353.     read(fin, &device, sizeof(struct dev));
  354.     res = (double) device.res;
  355.     close(fin);
  356. }
  357.  
  358.  
  359. /*----------------------------------------------------------------------------*
  360.  | Routine:    char  * doinput (file_pointer)
  361.  |
  362.  | Results:    a line of input is read into "inputline".
  363.  |
  364.  | Side Efct:    "linenum" is incremented.
  365.  |
  366.  | Bugs:    lines longer than MAXINLINE are NOT checked, except for 
  367.  |        updating "linenum"
  368.  *----------------------------------------------------------------------------*/
  369.  
  370. char *doinput(fp)
  371. FILE *fp;
  372. {
  373.     char *k;
  374.  
  375.  
  376.     if ((k = fgets(inputline, MAXINLINE, fp)) == NULL)
  377.     return k;
  378.     if (index (inputline, '\n'))    /* ++ only if it's a complete line */
  379.         linenum++;
  380.     return (char*) !NULL;
  381. }
  382.  
  383.  
  384. /*----------------------------------------------------------------------------*
  385.  | Routine:    initpic ( )
  386.  |
  387.  | Results:    sets all parameters to the normal defaults, possibly overridden
  388.  |        by a setdefault command.  Initilaize the picture variables,
  389.  |        and output the startup commands to troff to begin the picture.
  390.  *----------------------------------------------------------------------------*/
  391.  
  392. initpic()
  393. {
  394.     register int i;
  395.  
  396.     for (i = 0; i < STYLES; i++) {    /* line thickness defaults */
  397.     thick[i] = defthick[i];
  398.     }
  399.     for (i = 0; i < FONTS; i++) {    /* font name defaults */
  400.     tfont[i] = deffont[i];
  401.     }
  402.     for (i = 0; i < SIZES; i++) {    /* font size defaults */
  403.     tsize[i] = defsize[i];
  404.     }
  405.     for (i = 0; i < NSTIPPLES; i++) {    /* stipple font file default indices */
  406.     stipple_index[i] = defstipple_index[i];
  407.     }
  408.     stipple = defstipple;
  409.  
  410.     gremlinfile[0] = 0;        /* filename is "null" */
  411.     setdefault = 0;        /* this is not the default settings (yet) */
  412.  
  413.     toppoint = BIG;        /* set the picture bounds out */
  414.     bottompoint = -BIG;        /* of range so they'll be set */
  415.     leftpoint = BIG;        /* by "savebounds" on input */
  416.     rightpoint = -BIG;
  417.  
  418.     pointscale = defpoint;    /* Flag for scaling point sizes default. */
  419.     xscale = scale;        /* default scale of individual pictures */
  420.     width = 0.0;        /* size specifications input by user */
  421.     height = 0.0;
  422.  
  423.     linethickness = DEFTHICK;    /* brush styles */
  424.     linmod = DEFSTYLE;
  425.     brushinvalid = 1;        /* Force HGSetBrush to output brush info for
  426.                  * next element. */
  427. }
  428.  
  429.  
  430. /*----------------------------------------------------------------------------*
  431.  | Routine:    conv (file_pointer, starting_line)
  432.  |
  433.  | Results:    at this point, we just passed a ".GS" line in the input file.
  434.  |        conv reads the input and calls "interpret" to process commands,
  435.  |        gathering up information until a ".GE" line is found.  It then
  436.  |        calls "HGPrint" to do the translation of the gremlin file to
  437.  |        troff commands.
  438.  *----------------------------------------------------------------------------*/
  439.  
  440. conv(fp)
  441. register FILE *fp;
  442. {
  443.     register FILE *gfp = NULL;    /* input file pointer */
  444.     register int done = 0;        /* flag to remember if finished */
  445.     register ELT *e;    /* current element pointer */
  446.     ELT *PICTURE;        /* whole picture data base pointer */
  447.     double temp;        /* temporary calculating area */
  448.     POINT ptr;    /* coordinates of a point to pass to "mov" routine */
  449.     int flyback;    /* flag "want to end up at the top of the picture?" */
  450.  
  451.  
  452.     initpic();            /* set defaults, ranges, etc. */
  453.     strcpy (GScommand, inputline);    /* save ".GS" line for later */
  454.     do {
  455.         done = (doinput(fp) == NULL);             /* test for EOF */
  456.         flyback = *c3 == 'F';               /* and .GE or .GF */
  457.         done |= (*c1 == '.' && *c2 == 'G' && (*c3 == 'E' || flyback));
  458.  
  459.         if (done) {
  460.         if (setdefault) savestate();
  461.  
  462.         if (!gremlinfile[0]) {
  463.             if(!setdefault)
  464.             error("no picture filename");
  465.             return;
  466.         }
  467.         if ((gfp = fopen(gremlinfile, "r")) == NULL) {
  468.             char name[MAXINLINE]; /* if the file isn't in the current */
  469.                     /* directory, try the gremlin library */
  470.             sprintf(name, "%s%s", gremlib, gremlinfile);
  471.             if ((gfp = fopen(name, "r")) == NULL) {
  472.             error("can't open %s", gremlinfile);
  473.             return;
  474.             }
  475.         }
  476.         PICTURE = DBRead(gfp);            /* read picture file */
  477.         fclose(gfp);
  478.         if (DBNullelt(PICTURE))
  479.             return;        /* if a request is made to make the */
  480.                     /* picture fit into a specific area, */
  481.                     /* set the scale to do that. */
  482.  
  483.         SCREENtoINCH = (SUNFILE) ? 0.014 : 0.02;
  484.  
  485.         if (stipple == (char *) NULL)    /* if user forgot stipple */
  486.             if (has_polygon(PICTURE))    /* and picture has a polygon */
  487.             stipple = DEFSTIPPLE;    /* then set the default */
  488.  
  489.         if ((temp = bottompoint - toppoint) < 0.1) temp = 0.1;
  490.         temp = (height != 0.0) ? height / (temp * SCREENtoINCH)  : BIG;
  491.         if ((troffscale = rightpoint - leftpoint) < 0.1) troffscale=0.1;
  492.         troffscale = (width != 0.0) ?
  493.                 width / (troffscale * SCREENtoINCH)  : BIG;
  494.         if (temp == BIG && troffscale == BIG) {
  495.             troffscale = xscale;
  496.         } else {
  497.             if (temp < troffscale) troffscale = temp;
  498.         }                /* here, troffscale is the */
  499.                         /* picture's scaling factor */
  500.         if (pointscale) {
  501.             register int i;        /* do pointscaling here, when */
  502.                          /* scale is known, before output */
  503.  
  504.             for (i = 0; i < SIZES; i++)
  505.             tsize[i] = (int) (troffscale * (double) tsize[i] + 0.5);
  506.  
  507.         }
  508.                            /* change to device units */
  509.         troffscale *= SCREENtoINCH * res;    /* from screen units */
  510.  
  511.         ytop = toppoint * troffscale;        /* calculate integer */
  512.         ybottom = bottompoint * troffscale;    /* versions of the */
  513.         xleft = leftpoint * troffscale;        /* picture limits */
  514.         xright = rightpoint * troffscale;
  515.                     /* save stuff in number registers, */
  516.                     /*   register g1 = picture width and */
  517.                     /*   register g2 = picture height, */
  518.                     /*   set vertical spacing, no fill, */
  519.                     /*   and break (to make sure picture */
  520.                     /*   starts on left), and put out the */
  521.                     /*   user's ".GS" line. */
  522.         printf(
  523. ".br\n.nr g1 %du\n.nr g2 %du\n%s.nr g3 \\n(.f\n.nr g4 \\n(.s\n\\0\n.sp -1\n",
  524.             xright-xleft, ybottom-ytop, GScommand);
  525.  
  526.         if (stipple) {        /* stipple requested for this picture */
  527.             printf(".st %s\n", stipple);
  528.         }
  529.  
  530.         lastx = xleft;        /* note where we are, (upper left */
  531.         lastyline = lasty = ytop;    /* corner of the picture) */
  532.  
  533.         e = PICTURE;
  534.         while (!DBNullelt(e)) {    /* traverse picture;  print elements */
  535.             HGPrintElt(e);
  536.             e = DBNextElt(e);
  537.         }
  538.                 /* decide where to end picture */
  539.         if (flyback) {        /* end piture at upper left */
  540.             ptr.x = leftpoint;
  541.             ptr.y = toppoint;
  542.         } else {        /* end picture at lower left */
  543.             ptr.x = leftpoint;
  544.             ptr.y = bottompoint;
  545.         }
  546.         tmove(&ptr);        /* restore default line parameters, */
  547.                     /* restore everything to the way */
  548.                     /* it was before the .GS, then put */
  549.                     /* out the ".GE" line from user */
  550.         printf("\\D't %du'\\D's %du'\n", DEFTHICK, DEFSTYLE);
  551.         if (flyback) {        /* make sure we end up at top of */
  552.             printf(".sp -1\n");        /* picture if "flying back" */
  553.         }
  554.         if (stipple) {        /* restore stipple to previous */
  555.             printf(".st\n");
  556.         }
  557.         printf(".br\n.ft \\n(g3\n.ps \\n(g4\n%s", inputline);
  558.         } else {
  559.         interpret(inputline);    /* take commands from the input file */
  560.         }
  561.     } while (!done);
  562. }
  563.  
  564.  
  565. /*----------------------------------------------------------------------------*
  566.  | Routine:    savestate  ( )
  567.  |
  568.  | Results:    all the current  scaling / font size / font name / thickness /
  569.  |        pointscale  settings are saved to be the defaults.  Scaled
  570.  |        point sizes are NOT saved.  The scaling is done each time a
  571.  |        new picture is started.
  572.  |
  573.  | Side Efct:    scale, and def* are modified.
  574.  *----------------------------------------------------------------------------*/
  575.  
  576. savestate()
  577. {
  578.     register int i;
  579.  
  580.     for (i = 0; i < STYLES; i++) {    /* line thickness defaults */
  581.     defthick[i] = thick[i];
  582.     }
  583.     for (i = 0; i < FONTS; i++) {    /* font name defaults */
  584.     deffont[i] = tfont[i];
  585.     }
  586.     for (i = 0; i < SIZES; i++) {    /* font size defaults */
  587.     defsize[i] = tsize[i];
  588.     }
  589.     for (i = 0; i < NSTIPPLES; i++) {    /* stipple font file default indices */
  590.     defstipple_index[i] = stipple_index[i];
  591.     }
  592.     defstipple = stipple;    /* if stipple has been set, it's remembered */
  593.  
  594.     scale *= xscale;        /* default scale of individual pictures */
  595.     defpoint = pointscale;    /* flag for scaling pointsizes from x factors */
  596. }
  597.  
  598.  
  599. /*----------------------------------------------------------------------------*
  600.  | Routine:    savebounds (x_coordinate, y_coordinate)
  601.  |
  602.  | Results:    keeps track of the maximum and minimum extent of a picture
  603.  |        in the global variables:  left-, right-, top- and bottompoint.
  604.  |        "savebounds" assumes that the points have been oriented to
  605.  |        the correct direction.  No scaling has taken place, though.
  606.  *----------------------------------------------------------------------------*/
  607.  
  608. savebounds(x, y)
  609. float x;
  610. float y;
  611. {
  612.     if (x < leftpoint) leftpoint = x;
  613.     if (x > rightpoint) rightpoint = x;
  614.     if (y < toppoint) toppoint = y;
  615.     if (y > bottompoint) bottompoint = y;
  616. }
  617.  
  618.  
  619. /*----------------------------------------------------------------------------*
  620.  | Routine:    interpret (character_string)
  621.  |
  622.  | Results:    commands are taken from the input string and performed.
  623.  |        Commands are separated by the endofline, and are of the
  624.  |        format:
  625.  |            string1 string2
  626.  |
  627.  |        where string1 is the command and string2 is the argument.
  628.  |
  629.  | Side Efct:    font and size strings, plus the gremlin file name and the
  630.  |        width and height variables are set by this routine.
  631.  *----------------------------------------------------------------------------*/
  632.  
  633. interpret (line)
  634. char *line;
  635. {
  636.     char str1[MAXINLINE];
  637.     char str2[MAXINLINE];
  638.     register char *chr;
  639.     register int i;
  640.     double par;
  641.  
  642.     str2[0] = '\0';
  643.     sscanf(line, "%80s%80s", &str1[0], &str2[0]);
  644.     for (chr = &str1[0]; *chr; chr++)        /* convert command to */
  645.     if(isupper(*chr)) *chr = tolower(*chr);        /* lower case */
  646.     switch (str1[0]) {
  647.  
  648.     case '1':
  649.     case '2':    /* font sizes */
  650.     case '3':
  651.     case '4':
  652.         i = atoi(str2);
  653.         if (i > 0 && i < 1000)
  654.         tsize[str1[0] - '1'] = i;
  655.         else
  656.         error("bad font size value");
  657.         break;
  658.  
  659.     case 'r':    /* roman */
  660.         if(str2[0] < '0') goto nofont;
  661.         tfont[0] = malloc(strlen(str2) + 1);
  662.         strcpy(tfont[0], str2);
  663.         break;
  664.  
  665.     case 'i':    /* italics */
  666.         if(str2[0] < '0') goto nofont;
  667.         tfont[1] = malloc(strlen(str2) + 1);
  668.         strcpy(tfont[1], str2);
  669.         break;
  670.  
  671.     case 'b':    /* bold */
  672.         if(str2[0] < '0') goto nofont;
  673.         tfont[2] = malloc(strlen(str2) + 1);
  674.         strcpy(tfont[2], str2);
  675.         break;
  676.  
  677.     case 's':    /* special */
  678.         if (str1[1] == 'c') goto scalecommand;    /* or scale */
  679.  
  680.         if(str2[0] < '0') {
  681.     nofont:    error("no fontname specified");
  682.         break;
  683.         }
  684.         if (str1[1] == 't') goto stipplecommand;    /* or stipple */
  685.  
  686.         tfont[3] = malloc(strlen(str2) + 1);
  687.         strcpy(tfont[3], str2);
  688.         break;
  689.  
  690.     case 'l':    /* l */
  691.         if ((str1[1] < '1') || (str1[1] > '8'))
  692.         goto stipplecommand;
  693.  
  694.         /* else set stipple index */
  695.         i = atoi(str2);
  696.         if (i >= 0 && i < 256)
  697.         stipple_index[str1[1] - '1'] = i;
  698.         else
  699.         error("bad stipple index value");
  700.         break;
  701.  
  702.     stipplecommand:    /* stipple */
  703.         stipple = malloc(strlen(str2) + 1);
  704.         strcpy(stipple, str2);
  705.         break;
  706.  
  707.     case 'o':    /* oldstipplemap */
  708.         oldstipmap = TRUE;
  709.         break;
  710.  
  711.     case 't':    /* thick */
  712.         thick[2] = atoi(str2);
  713.         break;
  714.  
  715.     case 'm':    /* medium */
  716.         thick[5] = atoi(str2);
  717.         break;
  718.  
  719.     case 'n':    /* narrow */
  720.         thick[0] = thick[1] = thick[3] = thick[4] = atoi(str2);
  721.         break;
  722.  
  723.     case 'x':    /* x */
  724.     scalecommand:    /* scale */
  725.         par = atof(str2);
  726.         if (par > 0.0)
  727.         xscale *= par;
  728.         else
  729.         error("illegal scale value");
  730.         break;
  731.  
  732.     case 'f':    /* file */
  733.         strcpy(gremlinfile, str2);
  734.         break;
  735.  
  736.     case 'w':    /* width */
  737.         width = atof(str2);
  738.         if (width < 0.0) width = -width;
  739.         break;
  740.  
  741.     case 'h':    /* height */
  742.         height = atof(str2);
  743.         if (height < 0.0) height = -height;
  744.         break;
  745.  
  746.     case 'd':    /* defaults */
  747.         setdefault = 1;
  748.         break;
  749.  
  750.     case 'p':    /* pointscale */
  751.         if (strcmp("off", str2))
  752.         pointscale = 1;
  753.         else
  754.         pointscale = 0;
  755.         break;
  756.  
  757.     default: 
  758.         error("unknown command, %s",str1);
  759.         exit(8);
  760.         break;
  761.     };
  762. }
  763.  
  764.  
  765. /*
  766.  * return TRUE if picture contains a polygon
  767.  * otherwise FALSE
  768.  */
  769. has_polygon(elist)
  770. register ELT *elist;
  771. {
  772.     while (!DBNullelt(elist)) {
  773.     if (elist->type == POLYGON)
  774.         return(1);
  775.     elist = DBNextElt(elist);
  776.     }
  777.  
  778.     return(0);
  779. }
  780. @
  781.  
  782.  
  783. 1.2
  784. log
  785. @Was forgetting to output initial brush settings to Ditroff.
  786. @
  787. text
  788. @d256 1
  789. @
  790.  
  791.  
  792. 1.1
  793. log
  794. @Initial revision
  795. @
  796. text
  797. @d122 2
  798. d391 2
  799. @
  800.